package com.xiongzai.lambda;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * JDK8 时间API，包含LocalDateTime，LocalDate，LocalTime
 * @author 熊崽
 */
public class LocalDateTimeApi {
    private static final Logger logger = LoggerFactory.getLogger(LocalDateTimeApi.class);
    
    public static void main(String[] args) {
        
        conversion();
        
        compareTo();
        
        formatt();
    }
    
    /**
     * localDate、LocalTime、LocalDateTime与String/Date相互转换并格式化的方法合辑
     */
    private static void formatt() {
        /*一、日期时间类型转换成字符串*/
        /*localDate --> String*/
        LocalDate localDate = LocalDate.now();
        String format1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);      /*yyyyMMdd*/
        String format2 = localDate.format(DateTimeFormatter.ISO_DATE);            /*yyyy-MM-dd*/
        logger.info(new StringBuilder().append("localDate --> String：(yyyyMMdd)->").append(format1).toString());
        logger.info(new StringBuilder().append("localDate --> String：(yyyy-MM-dd)->").append(format2).toString());
        
        
        /*2.LocalTime  --> String*/
        LocalTime localTime = LocalTime.now();
        String format3 = localTime.format(DateTimeFormatter.ISO_TIME);            /*16:58:49.76*/
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss");
        String format4 = localTime.format(formatter);
        logger.info(new StringBuilder().append("LocalTime --> String(ISO_TIME)->").append(format3).toString());
        logger.info(new StringBuilder().append("LocalTime --> String(hh:mm:ss)->").append(format4).toString());
        
        /*3.LocalDateTime  --> String*/
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        String format5 = localDateTime.format(formatter2);
        logger.info(new StringBuilder().append("LocalDateTime --> String(yyyy-MM-dd hh:mm:ss)->").append(format5).toString());
        
        /*二、字符串转换成日期时间类型*/
        /* String --> LocalDate*/
        LocalDate localDate1 = LocalDate.parse("2021-10-22");
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String format = localDate1.format(pattern);
        logger.info(new StringBuilder().append("2021-10-22 --> yyyy年MM月dd日 :->").append(format).toString());
        
        /*String --> LocalTime*/
        LocalTime localTime2 = LocalTime.parse("17:43:53");
        logger.info(new StringBuilder().append("String --> LocalTime(17:43:53)->").append(localTime2).toString());
        
        /*String -->LocalDateTime*/
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"); /*12小时*/
        DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); /*24小时*/
        LocalDate localDate3 = LocalDate.parse("2021-10-22 05:43:53", formatter3);
        LocalDate localDate4 = LocalDate.parse("2021-10-22 17:43:53", formatter4);
        logger.info(new StringBuilder().append("String --> LocalDateTime(12小时)->").append(localDate3).toString());
        logger.info(new StringBuilder().append("String --> LocalDateTime(24小时)->").append(localDate4).toString());
        
        Date startDt = new Date();
        /*将 Date 转换为 LocalDateTime 并且格式化为 yyyy-MM-dd HH:mm:ss，ZoneId.systemDefault() 代表系统默认时区*/
        String format6 = startDt.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(DateTimeFormatter.ISO_DATE_TIME);
        /*将 Date 转换为 LocalDate 并且格式化为 yyyyMMdd，ZoneId.systemDefault() 代表系统默认时区*/
        String format7 = startDt.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(DateTimeFormatter.BASIC_ISO_DATE);
        /*将 Date 转换为 LocalDate,  8 代表系统中国时区*/
        String format8 = startDt.toInstant().atZone(ZoneOffset.ofHours(8)).toLocalDate().format(DateTimeFormatter.BASIC_ISO_DATE);
        logger.info(new StringBuilder().append("Date --> LocalDateTime(yyyy-MM-dd HH:mm:ss)->").append(format6).toString());
        logger.info(new StringBuilder().append("Date --> LocalDate(yyyyMMdd)->").append(format7).toString());
        logger.info(new StringBuilder().append("Date --> LocalDate(yyyyMMdd)->").append(format8).toString());
    }
    
    /**
     * 比较2个时间的方法合辑
     */
    private static void compareTo() {
        /*此时此刻*/
        LocalDateTime now = LocalDateTime.now();
        /*2021-10-23T16:30:46.819*/
        logger.info(new StringBuilder().append("LocalDateTime.now()->").append(now).toString());
        
        /*明天的这个时刻*/
        LocalDateTime nowAtTomorrow = now.plusDays(1);
        /*2021-10-24T16:30:46.819*/
        logger.info(new StringBuilder().append("LocalDateTime.now().plusDays(1)->").append(now).toString());
        
        /*
         * compareTo:相比的结果，返回数值类型
         * isAfter：左边是否大于右边，返回布尔类型
         * isBefore：左边是否小于右边，返回布尔类型
         * isEqual：左边是否等于右边，返回布尔类型
         */
        
        /* 如果方法左边小于右边，则返回: -1*/
        /*LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
        LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
        a.isAfter(b) == false
        a.isAfter(a) == false
        b.isAfter(a) == true*/
        int i = now.compareTo(nowAtTomorrow);
        boolean flat = nowAtTomorrow.isAfter(now);
        logger.info(new StringBuilder().append("今天>明天：->").append(i).toString());
        logger.info(new StringBuilder().append("今天>明天：->").append(flat).toString());
        
        /* 如果方法左边大于右边，则返回: 1*/
        /*LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
        LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
        a.isBefore(b) == true
        a.isBefore(a) == false
        b.isBefore(a) == false*/
        i = nowAtTomorrow.compareTo(now);
        flat = now.isBefore(nowAtTomorrow);
        logger.info(new StringBuilder().append("明天>今天：->").append(i).toString());
        logger.info(new StringBuilder().append("明天>今天：->").append(flat).toString());
        
        /*如果方法左边等于右边，则返回: 0*/
        /*LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
        LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
        a.isEqual(b) == false
        a.isEqual(a) == true
        b.isEqual(a) == false*/
        i = now.compareTo(now);
        flat = now.isEqual(now);
        logger.info(new StringBuilder().append("今天==今天：->").append(i).toString());
        logger.info(new StringBuilder().append("今天==今天：->").append(flat).toString());
    }
    
    /**
     * LocalDate、LocalDateTime、Date、String相互转换方法合辑
     */
    private static void conversion() {
        /*1.LocalDate转Date*/
        LocalDate nowLocalDate = LocalDate.now();
        Date date = Date.from(nowLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        logger.info(new StringBuilder().append("LocalDate->").append(nowLocalDate).toString());
        logger.info(new StringBuilder().append("Date->").append(date).toString());
        
        /*2.LocalDateTime转Date*/
        LocalDateTime localDateTime = LocalDateTime.now();
        Date date2 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        logger.info(new StringBuilder().append("LocalDateTime->").append(localDateTime).toString());
        logger.info(new StringBuilder().append("Date->").append(date2).toString());
        
        /*3.Date转LocalDateTime(LocalDate)*/
        Date date3 = new Date();
        LocalDate localDate = date3.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDateTime localDateTime3 = date3.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        logger.info(new StringBuilder().append("Date->").append(date3).toString());
        logger.info(new StringBuilder().append("LocalDate->").append(localDate).toString());
        logger.info(new StringBuilder().append("LocalDateTime->").append(localDateTime3).toString());
        
        /*4.String 转 LocalDate 转 Date*/
        String day = "2021-10-22";
        Date date4 = Date.from(LocalDate.parse(day.replaceAll("/", "-")).atStartOfDay(ZoneId.systemDefault()).toInstant());
        logger.info(new StringBuilder().append("String 转 LocalDate 转 Date->").append(date4).toString());
        
        /*5. Date 转 LocalDate 转 String(yyyy-MM-dd)*/
        Date date5 = new Date();
        String taskStartDt = date5.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(DateTimeFormatter.ISO_DATE);
        logger.info(new StringBuilder().append("Date 转 LocalDate 转 String(yyyy-MM-dd)->").append(taskStartDt).toString());
        
        /*6.LocalDate转时间戳*/
        LocalDate localDate6 = LocalDate.now();
        long longtimestamp = localDate6.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
        logger.info(new StringBuilder().append("LocalDate转时间戳->").append(longtimestamp).toString());
        
        
        /*7.LocalDateTime转时间戳*/
        LocalDateTime localDateTime7 = LocalDateTime.now();
        longtimestamp = localDateTime7.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        logger.info(new StringBuilder().append("LocalDateTime转时间戳->").append(longtimestamp).toString());
        
        /*8.时间戳转LocalDateTime(LocalDate)*/
        longtimestamp = System.currentTimeMillis();
        LocalDate localDate8 = Instant.ofEpochMilli(longtimestamp).atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDateTime localDateTime8 = Instant.ofEpochMilli(longtimestamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
        logger.info(new StringBuilder().append("时间戳转LocalDate->").append(localDate8).toString());
        logger.info(new StringBuilder().append("时间戳转LocalDateTime->").append(localDateTime8).toString());
    }
}
